#include <clusnet/net/TcpServer.h>
#include <iostream>

int main(int argc, char* argv[])
{
    InitLogging();
    try
    {
        if (argc < 4)
        {
            LOG(ERROR) << "Usage: TcpServer_test <port> <thread_num> <io_num>";
            return 1;
        }

        clusnet::net::TcpServer server(boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), std::atoi(argv[1])));
        server.setNewConnectionCallback([](clusnet::net::TcpConnectionPtr& conn)
        {
            LOG(INFO) << "new connection. from " << conn->remoteEndpoint().address() << ":" << conn->remoteEndpoint().port() << " to " << conn->localEndpoint().address() << ":" << conn->localEndpoint().port();
            conn->safeStartReceive();
        });
        server.setCloseCallback([](clusnet::net::TcpConnectionPtr& conn)
        {
            LOG(INFO) << "connection close. remote address: " << conn->remoteEndpoint().address() << ":" << conn->remoteEndpoint().port();
        });
        server.setMessageCallback([](clusnet::net::TcpConnectionPtr& conn, clusnet::net::TcpUniqDataPacketPtr&& data)
        {
            LOG(INFO) << "recv from " << conn->remoteEndpoint().address() << ":" << conn->remoteEndpoint().port() << " " << data->dataLength() << " bytes";
            conn->safeAsyncWrite(std::move(data));
        });
        server.setWriteCompleteCallback([](clusnet::net::TcpConnectionPtr& conn, const clusnet::net::TcpDataPacketPtr& data)
        {
            LOG(INFO) << "send to " << conn->remoteEndpoint().address() << ":" << conn->remoteEndpoint().port() << " " << data->dataLength() << " bytes";
        });
        server.start(std::atoi(argv[2]), std::atoi(argv[3]));

        std::string line;
        while (std::cin >> line)
        {
            if (line == "stop")
            {
                LOG(INFO) << "stop server";
                server.stop();
                break;
            }
        }
    }
    catch (std::exception& e)
    {
        LOG(ERROR) << "Exception: " << e.what();
    }

    return 0;
}
